home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / misc / aaboing.lha / AABoing.c next >
Encoding:
C/C++ Source or Header  |  1993-02-11  |  11.3 KB  |  368 lines

  1. /* $$TABS=4 */
  2.  
  3. #include <exec/types.h>
  4. #include <clib/exec_protos.h>
  5. #include <graphics/view.h>
  6. #include <graphics/gfxbase.h>
  7. #include <graphics/videocontrol.h>
  8. #include <graphics/displayinfo.h>
  9. #include <intuition/intuition.h>
  10. #include <intuition/screens.h>
  11. #include <libraries/dos.h>
  12. #include <graphics/sprite.h>
  13. #include <stdio.h>
  14.  
  15. #ifndef VC_IntermediateCLUpdate
  16. /* define post-39.106 tags */
  17.  
  18. #define VC_IntermediateCLUpdate        0x80000080
  19.                             /* default=true. When set graphics will
  20.                              update the intermediate copper lists
  21.                              on color changes, etc. When false,
  22.                              it won't, and will be faster. */
  23. #define VC_IntermediateCLUpdate_Query    0x80000081
  24. #endif
  25.  
  26. /* This demo demonstrates the following OS3.0 & AA features:
  27.     
  28.     Wide Sprites
  29.     Fast Scrolling
  30.     Using bordersprites to make multiple viewports look like
  31.        a single viewport.
  32.     
  33.     Relatively "safe" stealing of sprite 0 from intuition.
  34.     A trick for speeding up ScrollVPort under ks39.106.
  35.  
  36.     NOTE: This demo was originally written as part of a series
  37.     of self-runing demos, each of which could be quit using the
  38.     joystick button. In order to make the minimum change necessary to
  39.     be able to quit with the left mouse button, I simply left the
  40.     hardware-banging button reading code in, and added the extra check for
  41.     the other button. This is NOT a recommended way of reading the
  42.     LMB. Far better would be to add an input handler which set a flag
  43.     when the button was depressed, and loop on that.
  44.  
  45.  
  46. */
  47.  
  48.  
  49.  
  50. #define NSLICES 4
  51. #define VPMODE (0x8000 | SPRITES)
  52. #define SLICESPACING (200/NSLICES)
  53. #define VPWIDTH 640
  54. #define VPHEIGHT (SLICESPACING-2)
  55. #define BMWIDTH (VPWIDTH*2)
  56. #define BMHEIGHT VPHEIGHT
  57. #define BMDEPTH 4
  58.  
  59. /*#define SETCOLOR(x) *((UWORD *) 0xdff180)=x */
  60. #define SETCOLOR(x)
  61.  
  62.  
  63. struct View myview;
  64. struct ViewPort myvp[NSLICES];
  65. struct ViewPortExtra *myvpe[NSLICES];
  66. struct RasInfo myri[NSLICES];
  67. struct ColorMap *mycm[NSLICES];
  68. struct BitMap *slicebm;
  69. struct RastPort myrp;
  70.  
  71. WORD rx[NSLICES],dx[NSLICES]={ -7*32, 6*32,-6*32,7*32 };
  72.  
  73. struct GfxBase *GfxBase;
  74.  
  75. extern UBYTE far Logo[];
  76.  
  77. int oldp=65536;
  78.  
  79.  
  80. UBYTE got[8]={-1,-1,-1,-1,-1,-1,-1,-1};
  81.  
  82. struct ExtSprite *boing00[20],*boing01[20],*boing10[20],*boing11[20],*boing20[20],*boing21[20];
  83. int spx[4],spy[4],spdx[4],spdy[4];
  84. struct View *oldview;
  85.  
  86. void Fail(char *msg)
  87. {
  88.     int i;
  89.     if (GfxBase->ActiView==&myview) { LoadView(oldview); WaitTOF(); }
  90.     if (msg) printf("%s\n",msg);
  91.     if (oldp != 65536) SetTaskPri(FindTask(0),oldp);
  92.     for(i=0;i<8;i++) if (got[i] != -1) FreeSprite(got[i]);
  93.     for(i=0;i<20;i++)
  94.     {
  95.         if (boing00[i]) FreeSpriteData(boing00[i]);
  96.         if (boing01[i]) FreeSpriteData(boing01[i]);
  97.         if (boing10[i]) FreeSpriteData(boing10[i]);
  98.         if (boing11[i]) FreeSpriteData(boing11[i]);
  99.         if (boing20[i]) FreeSpriteData(boing20[i]);
  100.         if (boing21[i]) FreeSpriteData(boing21[i]);
  101.     }
  102.     for(i=0;i<NSLICES;i++)
  103.     {
  104.         if (mycm[i]) FreeColorMap(mycm[i]);
  105.         FreeVPortCopLists(myvp+i);
  106.         if (myvpe[i]) GfxFree(myvpe[i]);
  107.     }
  108.  
  109.     if (myview.LOFCprList) FreeCprList(myview.LOFCprList);
  110.     if (myview.SHFCprList) FreeCprList(myview.SHFCprList);
  111.     if (slicebm) FreeBitMap(slicebm);
  112.     if (GfxBase) CloseLibrary((struct Library *) GfxBase);
  113.     if (msg) exit(0);
  114. }
  115.  
  116.  
  117. struct Library *openlib(char *name,ULONG version)
  118. {
  119.     struct Library *t1;
  120.     t1=OpenLibrary(name,version);
  121.     if (! t1)
  122.     {
  123.         printf("error- needs %s version %d\n",name,version);
  124.         Fail(0l);
  125.     }
  126.     else return(t1);
  127. }
  128.  
  129.  
  130.  
  131.  
  132. ULONG colortab[3*16+2];
  133.  
  134. struct BitMap spbitmap;
  135. UBYTE bmdata[16*100*2];
  136. ULONG smartgfx=0x12345678;
  137.  
  138. char fname[]="progdir:boing.0.00.lo.128x100x2";
  139.  
  140. main()
  141. {
  142.     int i,j,tempc[3],fhandle,newsp,lastsp;
  143.     void *temp;
  144.  
  145.     GfxBase=(struct GfxBase *) openlib("graphics.library",39);
  146.  
  147.     InitBitMap(&spbitmap,2,128,100);
  148.     for(i=0;i<20;i++)
  149.     {
  150.         fname[6+8]=((i+i)/10)+'0';
  151.         fname[8+8]=((i+i) % 10)+'0';
  152.         fhandle=Open(fname,MODE_OLDFILE);
  153.         if (! fhandle) Fail("can't open file");
  154.         Read(fhandle,bmdata,16*100*2);
  155.         Close(fhandle);
  156.         spbitmap.Planes[0]=bmdata;
  157.         spbitmap.Planes[1]=bmdata+16*100;
  158.         boing00[i]=(struct ExtSprite *) AllocSpriteData(&spbitmap,SPRITEA_Width,64,0);
  159.         boing10[i]=(struct ExtSprite *) AllocSpriteData(&spbitmap,SPRITEA_Width,64,0);
  160.         boing20[i]=(struct ExtSprite *) AllocSpriteData(&spbitmap,SPRITEA_Width,64,0);
  161.         if (! boing00[i]) Fail("can't get sprite ram");
  162.         if (! boing10[i]) Fail("can't get sprite ram");
  163.         if (! boing20[i]) Fail("can't get sprite ram");
  164.         spbitmap.Planes[0]+=8; spbitmap.Planes[1]+=8;
  165.         boing01[i]=(struct ExtSprite *) AllocSpriteData(&spbitmap,SPRITEA_Width,64,0);
  166.         boing11[i]=(struct ExtSprite *) AllocSpriteData(&spbitmap,SPRITEA_Width,64,0);
  167.         boing21[i]=(struct ExtSprite *) AllocSpriteData(&spbitmap,SPRITEA_Width,64,0);
  168.         if (! boing01[i]) Fail("can't get sprite ram");
  169.         if (! boing11[i]) Fail("can't get sprite ram");
  170.         if (! boing21[i]) Fail("can't get sprite ram");
  171.     }
  172.  
  173.     /* the GetExtSprite calls below will fail if this system does not support
  174.        4x sprites */
  175.  
  176.     got[0]=GetExtSprite(boing00[0],GSTAG_SPRITE_NUM,7,0);
  177.     if (got[0]==-1)    Fail("can't get extsprite");
  178.     got[1]=GetExtSprite(boing01[0],GSTAG_SPRITE_NUM,1,0);
  179.     if (got[1]==-1) Fail("can't get extsprite");
  180.     got[2]=GetExtSprite(boing10[0],GSTAG_SPRITE_NUM,2,0);
  181.     if (got[2]==-1)    Fail("can't get extsprite");
  182.     got[3]=GetExtSprite(boing11[0],GSTAG_SPRITE_NUM,3,0);
  183.     if (got[3]==-1) Fail("can't get extsprite");
  184.     got[4]=GetExtSprite(boing20[0],GSTAG_SPRITE_NUM,4,0);
  185.     if (got[4]==-1)    Fail("can't get extsprite");
  186.     got[5]=GetExtSprite(boing21[0],GSTAG_SPRITE_NUM,5,0);
  187.     if (got[5]==-1) Fail("can't get extsprite");
  188.     boing00[0]->es_SimpleSprite.num=0; /* relatively safe way to use sprite 0 */
  189.  
  190.  
  191.     slicebm=(struct BitMap *) AllocBitMap(BMWIDTH,BMHEIGHT,BMDEPTH,BMF_CLEAR|BMF_DISPLAYABLE,0);
  192.     if (!slicebm) Fail("can't get bitmap");
  193.     for(i=0;i<BMDEPTH;i++)
  194.     {
  195.         for(j=0;j<BMHEIGHT;j++)
  196.         {
  197.             CopyMem(Logo+i*48*80+j*80,slicebm->Planes[i]+j*slicebm->BytesPerRow,80);
  198.             CopyMem(Logo+i*48*80+j*80,slicebm->Planes[i]+80+j*slicebm->BytesPerRow,80);
  199.         }
  200.     }
  201.  
  202.  
  203.     colortab[0]=(16<<16);
  204.     for(i=1;i<16;i++)
  205.     {
  206.         colortab[i*3+1]=i*0x11111111;
  207.         colortab[i*3+2]=((i+2) & 15)*0x11111111;
  208.         colortab[i*3+3]=((i+5) & 15)*0x11111111;
  209.     }
  210.  
  211.     InitView(&myview);
  212.     for(i=0;i<NSLICES;i++)
  213.     {
  214.         int dark=0;
  215.         mycm[i]=(struct ColorMap *) GetColorMap(32);
  216.         if (! mycm[i]) Fail("can't get colormap");
  217.         InitVPort(myvp+i);
  218.         myvp[i].ColorMap=mycm[i];
  219.         myvp[i].DHeight=VPHEIGHT;
  220.         myvp[i].DWidth=VPWIDTH;
  221.         myvp[i].Modes=VPMODE;
  222.         myvp[i].RasInfo=myri+i;
  223.         myri[i].BitMap=slicebm;
  224.         myvp[i].Next=myview.ViewPort;
  225.         myview.ViewPort=myvp+i;
  226.         myvp[i].DyOffset=i*SLICESPACING;
  227.         myvpe[i]=(struct ViewPortExtra *) GfxNew(VIEWPORT_EXTRA_TYPE);
  228.         if (! myvpe[i]) Fail("can't get vpextra");
  229.  
  230.         VideoControlTags(mycm[i],VTAG_VIEWPORTEXTRA_SET,myvpe[i],
  231.                         VTAG_BORDERSPRITE_SET,-1,0);
  232.  
  233.         VideoControlTags(mycm[i],VTAG_ATTACH_CM_SET,myvp+i,0);
  234.  
  235.     /* the tags below cause in (graphics 39.102 and up) ScrollVPort() to not update 
  236.        the intermediate copper lists. This only works safely in custom viewports, as 
  237.        intuition may re-use your intermediate copper lists if someone calls RethinkDisplay(). 
  238.        In Kickstart 39.116 and up, intuition handles this properly */
  239.  
  240.         VideoControlTags(mycm[i],VC_IntermediateCLUpdate,0,0);
  241.         VideoControlTags(mycm[i],VC_IntermediateCLUpdate_Query,&smartgfx,0);
  242.  
  243.         smartgfx=(smartgfx==0x12345678)?0:-1;
  244.  
  245.         for(j=17;j<32;j+=4)
  246.         {
  247.             SetRGB4CM(mycm[i],j,15-dark,15-dark,15-dark);
  248.             SetRGB4CM(mycm[i],j+1,15-dark,7-(dark/2),7-(dark/2));
  249.             SetRGB4CM(mycm[i],j+2,15-dark,0,0);
  250.             dark+=2;
  251.         }
  252.     /* set sprite to playfield priorities so that one sprite pair is in front, one in the middle,
  253.        and one behind. See HW manual */
  254.  
  255.         VideoControlTags(mycm[i],VTAG_PF2_TO_SPRITEPRI_SET, (i&1)?1:2, 0 );
  256.         LoadRGB32(myvp+i,colortab);
  257.         MakeVPort(&myview,myvp+i);
  258.     }
  259.     MrgCop(&myview);
  260.     oldview=GfxBase->ActiView;
  261.     LoadView(&myview);
  262.  
  263.     spdx[0]=64; spx[0]=0; spdy[0]=32;
  264.     spdx[1]=-64; spx[1]=32*200; spdy[1]=-64;
  265.     spdx[2]=-128; spx[2]=32*100; spdy[2]=32*5;
  266.  
  267.     lastsp=0;
  268.  
  269.     /* set task priority to 30 so that beam-synchronized stuff will happen
  270.     reliably. It is NOT safe to call intuition with this high task priority */
  271.  
  272.     oldp=SetTaskPri(FindTask(0),30);
  273.  
  274.     for(i=0;(GfxBase->ActiView==&myview) && ((*((BYTE *) 0xbfe001) & 192)==192);i++)
  275.     {
  276.         WaitTOF();
  277.         SETCOLOR(0xf00);
  278.         if (i & 1)    /* color cycle */
  279.         {
  280.             tempc[0]=colortab[4]; tempc[1]=colortab[5];    tempc[2]=colortab[6];
  281.             CopyMem(colortab+1+6,colortab+1+3,3*14*4);
  282.             colortab[15*3+1]=tempc[0]; colortab[15*3+2]=tempc[1]; colortab[15*3+3]=tempc[2];
  283.         }
  284.         for(j=0;j<NSLICES;j++)
  285.         {
  286.             SETCOLOR(0xfff);
  287.             myri[j].RxOffset=rx[j]>>5;
  288.             rx[j]+=dx[j];
  289.             rx[j]=(rx[j] % (VPWIDTH*32));
  290.             if (rx[j]<0) rx[j]=VPWIDTH*32+rx[j];
  291.             if (smartgfx)
  292.                 ScrollVPort(myvp+j);
  293.             else {
  294.  
  295.     /*      in graphics <39.102, the following 2 tricks can be used to speed up ScrollVPort:
  296.  
  297.         By zeroing the DspIns->Copins of the viewport, ScrollVPort will not
  298.         attempt to modify the intermediate copper instructions for the viewport.
  299.         This modification is often not needed, and can slow things down. This
  300.         modification can be turned on and off by VideoControl in graphics 39.102
  301.         and up via VC_IntermediateCLUpdate. This tag will also affect LoadRGB32 and
  302.         ChangeVPBitMap.
  303.  
  304.         ScrollVPort must search the copper list for the ddfstart move instruction
  305.         in order ot modify it. This involves skipping over all of the color loading
  306.         instructions, which can be up to 2048 bytes long. So, before calling ScrollVPort,
  307.         this code bumps the hardware copper list pointers past the colors so that the
  308.         search will proceed faster. This requires knowledge of how many colors are needed
  309.         for your viewport. For a normal viewport, it is (1<<depth). For HAM, it is
  310.         1<<(depth-2), etc. This trick is NOT supported for versions of graphics after
  311.         39.102, since the number of instructions and ordering of copper instructions may
  312.         change, and since it does not produce a speedup in 39.102 anyway. Graphics
  313.         >=39.102 caches the exact location of ddfstart in the viewportextra, for greatly
  314.         increased performance.
  315.  
  316.         Neither of these tricks is safe in an intuition screeen under kick 39.106!!!
  317.  
  318.     */
  319.  
  320.         
  321.  
  322.                 temp=myvp[j].DspIns->CopIns; /* save intermed ptr */
  323.                 myvp[j].DspIns->CopIns=0;    /* zero it */
  324.                 myvp[j].DspIns->CopLStart+=BMDEPTH*2*2*2; /* skip colors */
  325.                 ScrollVPort(myvp+j);
  326.                 myvp[j].DspIns->CopLStart-=BMDEPTH*2*2*2; /* correct back */
  327.                 myvp[j].DspIns->CopIns=temp;
  328.             }
  329.             SETCOLOR(0x0f0);
  330.             if ((i ^j ) & 1) LoadRGB32(myvp+j,colortab);
  331.         }
  332.  
  333.         SETCOLOR(0xf);
  334.         MoveSprite(0,boing00[lastsp],spx[0]>>5,(spy[0]>>5));
  335.         MoveSprite(0,boing01[lastsp],(spx[0]>>5)+64,(spy[0]>>5));
  336.         MoveSprite(0,boing10[lastsp],spx[1]>>5,(spy[1]>>5));
  337.         MoveSprite(0,boing11[lastsp],(spx[1]>>5)+64,(spy[1]>>5));
  338.         MoveSprite(0,boing20[lastsp],spx[2]>>5,(spy[2]>>5));
  339.         MoveSprite(0,boing21[lastsp],(spx[2]>>5)+64,(spy[2]>>5));
  340.         newsp=(lastsp+2) % 20;
  341.         SETCOLOR(0xff);
  342.         ChangeExtSprite(0,boing00[lastsp],boing00[newsp],0);
  343.         ChangeExtSprite(0,boing01[lastsp],boing01[newsp],0);
  344.         ChangeExtSprite(0,boing10[lastsp],boing10[newsp],0);
  345.         ChangeExtSprite(0,boing11[lastsp],boing11[newsp],0);
  346.         ChangeExtSprite(0,boing20[lastsp],boing20[newsp],0);
  347.         ChangeExtSprite(0,boing21[lastsp],boing21[newsp],0);
  348.         SETCOLOR(0xf0f);
  349.         lastsp=newsp;
  350.         for(j=0;j<3;j++)
  351.         {
  352.             spx[j]+=spdx[j];
  353.             spy[j]+=spdy[j];
  354.             if ((spx[j] <0) || (spx[j]>((320-128)<<5)))
  355.             {
  356.                 spx[j]-=spdx[j];
  357.                 spdx[j]=-spdx[j];
  358.             }
  359.             if ((spy[j]<0) || (spy[j]>3200))
  360.             { spy[j]-=spdy[j]; spdy[j]=-spdy[j]; }
  361.             spdy[j]+=10;
  362.         }
  363.         SETCOLOR(0xf00);
  364.     }
  365.     for(i=0;!(*((BYTE *) 0xbfe001) & 192); i++) WaitTOF();
  366.     Fail(0);
  367. }
  368.